package com.retail.lottery.colalottery.service.impl;

import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.retail.lottery.colalottery.constant.ColaHttpUrlConfig;
import com.retail.lottery.colalottery.constant.RedisConstant;
import com.retail.lottery.colalottery.entity.WechatCustomer;
import com.retail.lottery.colalottery.enums.DeleteStatusEnum;
import com.retail.lottery.colalottery.enums.ErrorCodeEnum;
import com.retail.lottery.colalottery.exception.BusinessException;
import com.retail.lottery.colalottery.service.WechatCustomerService;
import com.retail.lottery.colalottery.mapper.WechatCustomerMapper;
import com.retail.lottery.colalottery.utils.DateUtil;
import com.retail.lottery.colalottery.utils.RedisUtils;
import com.retail.lottery.colalottery.vo.ResultVO;
import com.retail.lottery.colalottery.vo.request.SaveUserInfoRequest;
import com.retail.lottery.colalottery.vo.response.UserLoginNoCacheResponse;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.HandlerMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
* @author jarvis.zhang
* @description 针对表【wechat_customer(顾客微信小程序用户表)】的数据库操作Service实现
* @createDate 2025-06-04 11:18:17
*/
@Service
@Slf4j
public class WechatCustomerServiceImpl extends ServiceImpl<WechatCustomerMapper, WechatCustomer>
    implements WechatCustomerService{

    @Resource
    private ColaHttpUrlConfig colaHttpUrlConfig;
    @Resource
    private RedisTemplate redisTemplate;
    public static final String Authorization = "Authorization";

    @Override
    public ResultVO<?> userLoginNoCache(HttpServletRequest httpRequest,
                                        String buCode,
                                        String code,
                                        String source,
                                        String oneid,
                                        String encryptMobile) {
        String path = (String) httpRequest.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
        String userInfoTokenCacheKey = String.format(RedisConstant.REDIS_KEY_USER_INFO_TOKEN,
                buCode,
                code,
                oneid);
        //查询同一请求是否大幅度的提交请求，缓存是否有信息如果有则返回缓存的客户信息
        Object cacheUserInfo = redisTemplate.opsForValue().get(userInfoTokenCacheKey);
        if(Objects.nonNull(cacheUserInfo)){
            log.info("用户登录,根据缓存key{}获取获取用户信息:{}", userInfoTokenCacheKey, cacheUserInfo.toString());
            return ResultVO.succ(cacheUserInfo.toString());
        }

        Headers headers  = new Headers.Builder()
                .add(Authorization, httpRequest.getHeader(Authorization))
                .build();
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        Response response = null;
        try{
            Request request = new Request.Builder()
                    .headers(headers)
                    .url( colaHttpUrlConfig.getTargetUrl() + path + "?source=" + source)
                    .get()
                    .build();
            response = client.newCall(request).execute();
            if(response.code() == HttpStatus.OK.value()){
                UserLoginNoCacheResponse loginResponse = JSONObject.parseObject(response.body().string(), UserLoginNoCacheResponse.class);
                if(Objects.isNull(loginResponse) || Objects.isNull(loginResponse.getCustomerBasicInfo())){
                    throw new BusinessException(ErrorCodeEnum.REPEAT_OPTION);
                }
                userInfoSaveOrUpdate(getSaveUserInfoRequest(loginResponse, oneid, encryptMobile));
                saveAuthorization(loginResponse, buCode , code, oneid);
                return ResultVO.succ(JSONObject.toJSONString(loginResponse));
            }else{
                log.error("用户请求登录可乐失败,用户code{},返回信息{}", code, JSONObject.toJSONString(response));
                return ResultVO.error("登录失败");
            }
        }catch (Exception e){
            log.error("用户请求登录可乐,请求异常", e);
            return ResultVO.error("登录请求异常");
        }
    }

    @NotNull
    private SaveUserInfoRequest getSaveUserInfoRequest(UserLoginNoCacheResponse loginResponse,
                                                       String oneid,
                                                       String encryptMobil) {
        log.info("用户请求登录,请求参数:{},oneid:{},encryptMobil：{}", loginResponse, oneid, encryptMobil);
        SaveUserInfoRequest saveUserInfoRequest = new SaveUserInfoRequest();
        saveUserInfoRequest.setOpenId(loginResponse.getCustomerBasicInfo().getOpenId());
        saveUserInfoRequest.setOneid(oneid);
        saveUserInfoRequest.setEncryptMobile(encryptMobil);
        saveUserInfoRequest.setUnionId(loginResponse.getCustomerBasicInfo().getUnionId());
        saveUserInfoRequest.setNickName(loginResponse.getCustomerBasicInfo().getNickName());
        saveUserInfoRequest.setAvatarUrl(loginResponse.getCustomerBasicInfo().getAvatarUrl());
        saveUserInfoRequest.setStatus(loginResponse.getCustomerBasicInfo().getStatus());
        saveUserInfoRequest.setMobile(loginResponse.getCustomerBasicInfo().getMobile());
        saveUserInfoRequest.setCustomerId(loginResponse.getCustomerBasicInfo().getId());
        saveUserInfoRequest.setAgreementTime(loginResponse.getCustomerBasicInfo().getAgreementTime());
        saveUserInfoRequest.setAgreementInfo(loginResponse.getCustomerBasicInfo().getAgreementInfo());
        return saveUserInfoRequest;
    }

    private void saveAuthorization(UserLoginNoCacheResponse loginResponse, String buCode, String code, String oneid) {
        if(Objects.nonNull(loginResponse) &&
                Objects.nonNull(loginResponse.getCustomerBasicInfo()) &&
                StringUtils.isNotBlank(loginResponse.getCustomerBasicInfo().getOpenId())){
            log.info("用户登录成功,用户信息:{},添加缓存信息：{}", loginResponse.getCustomerBasicInfo().getOpenId() , loginResponse.getJwtString());
            redisTemplate.opsForValue().set(
                    String.format(RedisConstant.REDIS_KEY_USER_TOKEN,
                            buCode,
                            code), loginResponse.getJwtString(), 30, TimeUnit.MINUTES);
            redisTemplate.opsForValue().set(
                    String.format(RedisConstant.REDIS_KEY_USER_INFO_TOKEN,
                            buCode,
                            code,
                            oneid), JSONObject.toJSONString(loginResponse), 30, TimeUnit.MINUTES);

        }

    }

    @Override
    public ResultVO<?> userInfoSaveOrUpdate(SaveUserInfoRequest request) {
        //查询当前用户是否已经存在
        WechatCustomer wechatCustomer = baseMapper.selectOne(new LambdaQueryWrapper<WechatCustomer>()
                .eq(WechatCustomer::getOpenId, request.getOpenId())
                //.eq(StringUtils.isNotBlank(request.getOneid()), WechatCustomer::getOneid, request.getOneid())
                .eq(WechatCustomer::getIsDel, DeleteStatusEnum.no_del.getCode())
                .last("limit 1"));
        if (Objects.isNull(wechatCustomer)) {
            //add
            wechatCustomer = new WechatCustomer();
            wechatCustomer.setOpenId(request.getOpenId());
        }
        //防止已注册用户 更新信息 没传值导致数据丢失
        if(StringUtils.isNotBlank(request.getOneid())){
            wechatCustomer.setOneid(request.getOneid());
        }
        if(StringUtils.isNotBlank(request.getEncryptMobile())){
            wechatCustomer.setEncryptMobile(request.getEncryptMobile());
        }
        if(StringUtils.isNotBlank(request.getCustomerId())){
            wechatCustomer.setThirdCustomerId(request.getCustomerId());
        }
        wechatCustomer.setUnionId(request.getUnionId());
        wechatCustomer.setNickName(request.getNickName());
        wechatCustomer.setMobile(request.getMobile());
        wechatCustomer.setAvatarUrl(request.getAvatarUrl());
        wechatCustomer.setAgreementTime(DateUtil.stringToDate(request.getAgreementTime()));
        wechatCustomer.setAgreementInfo(request.getAgreementInfo());
        wechatCustomer.setStatus(request.getStatus());
        //增加redis校验，防止重发导致一个客户对应多条数据的情况
        String redisKey = String.format(RedisConstant.REDIS_KEY_USER_INFO_REPEAT, request.getOpenId(), request.getOneid());
        if(!RedisUtils.saveNX(redisKey, "1",  1, TimeUnit.SECONDS)){
            throw new BusinessException(ErrorCodeEnum.REPEAT_OPTION);
        }
        try{
//            v1.获加密接口的数据判断条件
//            v2.加密手机号不调用接口，页面跳转时提供
//            if(!StringUtils.isEmpty(request.getMobile()) && !Objects.equals(request.getMobile(), wechatCustomer.getMobile())){
//                //获取加密手机号
//                wechatCustomer.setEncryptMobile(encryptMobile(wechatCustomer));
//            }
            saveOrUpdate(wechatCustomer);
        }catch (Exception e){
            log.error("客户信息保存失败，锁:{}", redisKey, e);
            throw new BusinessException(ErrorCodeEnum.SYSTEM_ERROR);
        }finally{
            RedisUtils.del(redisKey);
        }
        return ResultVO.succ(wechatCustomer.getId());
    }

//    private String encryptMobile(WechatCustomer wechatCustomer) {
//        //TODO 可乐需提供手机号加密接口-获取加密后的手机号
//
//        log.info("手机号加密接口-获取加密后的手机号");
//        return "";
//    }
}




